package redisRepo

import (
	"context"
	"fmt"
	"math/rand"
	"sync"
	"time"

	"gitcode.com/common_go/redisdao"
)

type SnowflakeRepo struct {
}

var snowflakeOnce sync.Once

var snowflakeRepo *SnowflakeRepo

func NewSnowflakeRepo() *SnowflakeRepo {
	if snowflakeRepo != nil {
		return snowflakeRepo
	}
	snowflakeOnce.Do(func() {
		snowflakeRepo = new(SnowflakeRepo)
	})
	return snowflakeRepo
}

// 消息表默认分片数量
const udcToolsSnowflakeNodeKey = "udc_tools_snowflake_node"

// 自增 snowflakeNode
func (this *SnowflakeRepo) nodeIncr(ctx context.Context, typ string, increment float64) (err error) {

	rClient := redisdao.NewSimpleRedis("redis")
	_, err = rClient.ZIncrBy(ctx, udcToolsSnowflakeNodeKey, increment, typ).Result()

	return
}

// 获取 snowflakeNode
func (this *SnowflakeRepo) MakeSnowflakeNode(ctx context.Context, typ string) int64 {
	rClient := redisdao.NewSimpleRedis("redis")

	idxScore, err := rClient.ZScore(ctx, udcToolsSnowflakeNodeKey, typ).Result()
	if err != nil {
		if err.Error() != "redis: nil" {
			fmt.Println(err.Error())
			return this.randSnowflakeNode(ctx)
		}

		idxScore = 0
	}

	// 自增 snowflakeNode
	err = this.nodeIncr(ctx, typ, 1)
	if err != nil {
		return this.randSnowflakeNode(ctx)
	}

	return int64(idxScore)
}

// 随机生成 snowflakeNode
func (this *SnowflakeRepo) randSnowflakeNode(ctx context.Context) int64 {
	rand.Seed(time.Now().Unix())
	return rand.Int63n(1023)
}
